package Service.SurroundService;

import Factory.ParamChangeUtil;
import Model.SurroundModel.*;
import Service.ShipCalculate;

import java.io.IOException;


/**
 * 转换示例
 *
 * @author dingN
 * @date 2022/06/22
 */// 计算层实现实例
// TODO:  实现父类的Init方法，用于输入数据的初始化
// TODO： 实现父类的Calculate方法，未来所有的算法都只用来更改输入的几项数据的具体内容：目标队列，智能体小船队列，目标中心的，船队历史运行轨迹（可根据后续需求拓展）
// TODO:  实现父类的WorkingState方法，用来外部判断计算线程是否仍在工作
// TODO:  实现父类的ShutDown方法，用来结束运行
public class FirstOrderNumberRangeTargets extends ShipCalculate{

    ParamChangeUtil paramChangeUtil = new ParamChangeUtil(); // 数据转换器

    public static String name = "一阶包围不同数量目标组件";

    static int SleepTime; // 计算休眠间隔
    static volatile boolean isWorking = false; // 是否运行
    static volatile boolean isPrepareFinish = false; // 是否运行

    // 计算实例，包含计算信息
    public ShipSampling shipSampling;
    public Target target;

    /**
     * 转换示例
     * @param sleepTime 睡眠时间
     */
    public FirstOrderNumberRangeTargets(int sleepTime) {
        this.SleepTime = sleepTime;
        this.isWorking = true;
    }

    public void Init() {
        System.out.println(GetName() + "初始化了");
        this.initTarget();
        this.initShip();

        // 保存数据
        saveData(0);

        isPrepareFinish = true;
        System.out.println(GetName() + "初始化完成");
    }

    public void Calculate() {
        this.calculate();
    }

    public boolean GetWorkingState() {
        return this.isWorking;
    }

    public void ShutDown(){
        this.isWorking = false;
    };

    public String GetName() {
        return name;
    }

    public void SetCalSpeed(int sleepTime){ this.SleepTime = sleepTime;};

    public boolean GetPrepareState() {return this.isPrepareFinish;}

    // 初始化目标信息
    public void initTarget() {
        target = new Target();
        target.initCircularPosition();
        target.setCenter();
        try {
            target.initStaticVirtualTargets(target);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 初始化智能体
    public void initShip() {
        shipSampling = new ShipSampling();
        //初始化智能体
        shipSampling.createShip(target.virtualTargets.size(),target);
        //不断调整初始P值使得各个智能体对于目标估计中心位置初始值相同
        for (int i = 0; i < 20000; i++) {
            shipSampling.setφ(0.00005);
            shipSampling.setP(0.00005,target);
        }
    }

    /**
     * 保存数据
     * @param time 时间
     */
    public void saveData(double time) {
        //保存目标队列当前位置
        paramChangeUtil.SaveAllData(this, time);
        paramChangeUtil.SaveChartData(this);
    }


    // 计算并更新需要更新的数据
    public void calculate() {

        double t = 0.001;
        double count = 0;
        Parameter par = new Parameter(target.virtualTargets.size());
        double[][] A = par.setA();

        target.ControlVirtualTargets(t, target);

        isWorking = true;
        while (!shipSampling.formationFinish(t, target) && isWorking && isPrepareFinish) {
            try {
                Thread.sleep(SleepTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 通过控制器去修改智能体对于目标的各项数值
            target.ControlVirtualTargets(t, target);
            shipSampling.formationCotroller(t, target, A);

            // 保存数据
            saveData(count);

            // 时间跳到下一时刻
            count++;
            if (count >= 2500) break;
        }

        isWorking = false;
    }
}
